package org.ediba.siri.core.model.data;

import java.util.Collection;
import java.util.Date;
import java.util.Map;

import org.ediba.siri.core.Filter;
import org.ediba.siri.core.common.data.HibernateDomainDao;
import org.ediba.siri.core.model.domain.Model;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

public class HibernateModelDao extends HibernateDomainDao<Model, Integer> implements ModelDao {

	public HibernateModelDao() {super(Model.class);}

	@Override
	protected DetachedCriteria buildCriteria(Collection<Map<Filter,Object>> filters){
		DetachedCriteria detachedCriteria = this.buildCriteria();
		Disjunction or = Restrictions.disjunction();
		Conjunction and;

		for (Map<Filter, Object> filter : filters) {
			and = Restrictions.conjunction();
			for (Map.Entry<Filter,Object> entry: filter.entrySet())
				switch (entry.getKey()) {
				case FIRSTNAME:		and.add(Restrictions.ilike(Filter.FIRSTNAME.getProperty(), (String)entry.getValue(), MatchMode.START)); 
				break;
				case LASTNAME: 		and.add(Restrictions.ilike(Filter.LASTNAME.getProperty(), (String)entry.getValue(), MatchMode.START)); 
				break;
				case EMAIL: 		and.add(Restrictions.ilike(Filter.EMAIL.getProperty(), (String)entry.getValue(), MatchMode.ANYWHERE)); 
				break;
				case GENDER: 		and.add(Restrictions.eq(Filter.GENDER.getProperty(), (Boolean)entry.getValue())); 
				break;
				case BIRTHDATE: 	and.add(Restrictions.eq(Filter.BIRTHDATE.getProperty(), (Date)entry.getValue())); 
				break;
				case BIRTHDATE_MIN: 	and.add(Restrictions.ge(Filter.BIRTHDATE.getProperty(), (Date)entry.getValue())); 
				break;
				case BIRTHDATE_MAX: 	and.add(Restrictions.le(Filter.BIRTHDATE.getProperty(), (Date)entry.getValue())); 
				break;
				case MODELPHONE:	detachedCriteria.createAlias(Filter.MODELPHONE.getCollection(),Filter.MODELPHONE.getProperty());
									and.add(Restrictions.ilike(Filter.MODELPHONE.getPropertySearch(), (String)entry.getValue(),MatchMode.ANYWHERE));
				break;
				case MODELFEATURE:	detachedCriteria.createAlias(Filter.MODELFEATURE.getCollection(),Filter.MODELFEATURE.getProperty());
									and.add(Restrictions.ilike(Filter.MODELFEATURE.getPropertySearch(), (String)entry.getValue(),MatchMode.ANYWHERE)); 
				break;
				case MODELSCHOOL:	detachedCriteria.add(Restrictions.eq(Filter.MODELSCHOOL.getPropertyId(), (Integer)entry.getValue()));
				break;
				case TURN:	detachedCriteria.add(Restrictions.eq(Filter.TURN.getProperty(), (Integer)entry.getValue()));
				break;
				}
			or.add(and);
		}
		detachedCriteria.add(or);
		
		return detachedCriteria;
	}
}